package com.qkm.xinguan.repository.impl;

import com.alibaba.fastjson.JSON;
import com.qkm.xinguan.domain.entity.HouseInfo;
import com.qkm.xinguan.domain.infrastructure.security.LoginUser;
import com.qkm.xinguan.domain.infrastructure.utils.UserUtil;
import com.qkm.xinguan.domain.transform.dto.HouseInfoDTO;
import com.qkm.xinguan.exception.BusinessException;
import com.qkm.xinguan.response.Result;
import com.qkm.xinguan.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Results;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author zfj
 * @date 2022/1/13 -20:42
 */
@Service
@Slf4j
public class HouseInfoESService {

	@Autowired
	private RestHighLevelClient restHighLevelClient;
	//添加数据到ES中
	public Result addES(HouseInfoDTO houseInfoDTO) throws IOException {
		SearchRequest searchRequest = new SearchRequest("fj");

		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

		QueryBuilder query = QueryBuilders.rangeQuery("createTime");

		//对查询结果进行降序排序
		searchSourceBuilder.sort("createTime", SortOrder.DESC);


		searchSourceBuilder.query(query);
		searchSourceBuilder.from(0);
		searchSourceBuilder.size(1);

		searchRequest.source(searchSourceBuilder);
		int newId = 0;
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		for (SearchHit hit : search.getHits().getHits()) {
//			System.out.println(hit.getSourceAsMap());
			Map<String, Object> sourceAsMap = hit.getSourceAsMap();
			int id = (int)sourceAsMap.get("id");
			newId=id+1;
		}
		//添加动作
		LoginUser loginUser = UserUtil.getCurrentLoginUser();
		assert loginUser != null;
		HouseInfo houseInfo=new HouseInfo();
//		15,loginUser.getId(),loginUser.getPhoneNumber(),
//				houseInfoDTO.getAddress(),houseInfoDTO.getAddressInfo(),"0","0",houseInfoDTO.getAvatar(),
//				houseInfoDTO.getPrice(),houseInfoDTO.getHouseDescribe(),houseInfoDTO.getHouseType(),
//				houseInfoDTO.getArea(),houseInfoDTO.getDecorateState(),houseInfoDTO.getLeaseTerm(),"",
//				df.format(now),df.format(now)
		houseInfo.setId((long) newId);
		houseInfo.setUserId(loginUser.getId());
		houseInfo.setPhoneNumber(loginUser.getPhoneNumber());
		houseInfo.setAddress(houseInfoDTO.getAddress());
		houseInfo.setAddressInfo(houseInfoDTO.getAddressInfo());
		houseInfo.setState(0);
		houseInfo.setVerifyState(2);
		houseInfo.setAvatar(houseInfoDTO.getAvatar());
		houseInfo.setPrice(houseInfoDTO.getPrice());
		houseInfo.setHouseDescribe(houseInfoDTO.getHouseDescribe());
		houseInfo.setHouseType(houseInfoDTO.getHouseType());
		houseInfo.setHouseLayout(houseInfoDTO.getHouseLayout());
		houseInfo.setAvatar(houseInfoDTO.getAvatar());
		houseInfo.setDecorateState(houseInfoDTO.getDecorateState());
		houseInfo.setLeaseTerm(houseInfoDTO.getLeaseTerm());
		houseInfo.setErrorInfo(" ");
		houseInfo.setCreateTime(LocalDateTime.now());
		houseInfo.setModifiedTime(LocalDateTime.now());
		IndexRequest request = new IndexRequest("fj");
		request.timeout(TimeValue.timeValueSeconds(1));
		request.timeout("1s");
		//将我们的数据放入请求 json
		request.source(JSON.toJSONString(houseInfo), XContentType.JSON);
		//客户端发送请求
		IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);
		return Result.ok().data(index);
	}

	//编辑
	public Result editES(Long id,HouseInfoDTO houseInfoDTO) throws IOException {
		SearchRequest searchRequest = new SearchRequest("fj");
		//构建搜索条件
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		sourceBuilder.highlighter();
		//查询条件 QueryBuilders工具类实现
		//termQuery精确匹配
		//matchAllQuery匹配所有
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("id", id);
//		MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
		sourceBuilder.query(termQueryBuilder);
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		searchRequest.source(sourceBuilder);
		String realId=null;
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		for (SearchHit hit : search.getHits().getHits()) {
			realId=hit.getId();
		}
		UpdateRequest updateRequest = new UpdateRequest("fj",  realId);
		updateRequest.timeout("1s");
		HouseInfo houseInfo=new HouseInfo();
		houseInfo.setAddress(houseInfoDTO.getAddress());
		houseInfo.setAddressInfo(houseInfoDTO.getAddressInfo());
		houseInfo.setAvatar(houseInfoDTO.getAvatar());
		houseInfo.setPrice(houseInfoDTO.getPrice());
		houseInfo.setHouseDescribe(houseInfoDTO.getHouseDescribe());
		houseInfo.setHouseType(houseInfoDTO.getHouseType());
		houseInfo.setHouseLayout(houseInfoDTO.getHouseLayout());
		houseInfo.setAvatar(houseInfoDTO.getAvatar());
		houseInfo.setDecorateState(houseInfoDTO.getDecorateState());
		houseInfo.setLeaseTerm(houseInfoDTO.getLeaseTerm());
		updateRequest.doc(JSON.toJSONString(houseInfo), XContentType.JSON);
		UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		return Result.ok().data(update);
	}

	//出租
	public Result Lease(Long id) throws IOException {
		SearchRequest searchRequest = new SearchRequest("fj");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("id", id);
		searchSourceBuilder.query(termQueryBuilder);
		searchRequest.source(searchSourceBuilder);
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		String inId = null;
		for (SearchHit hit : search.getHits().getHits()) {
			inId = hit.getId();
		}
		UpdateRequest updateRequest = new UpdateRequest("fj", inId);
		updateRequest.timeout("1s");
		HashMap<String,Object> data=new HashMap<>();
		data.put("state",1);
		updateRequest.doc(JSON.toJSONString(data), XContentType.JSON);
		UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		log.info(String.valueOf(update.status()));
		return Result.ok().message("ElasticSearch审核通过");
	}

	public Result Fail(Long id) throws IOException {
		SearchRequest searchRequest = new SearchRequest("fj");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("id", id);
		searchSourceBuilder.query(termQueryBuilder);
		searchRequest.source(searchSourceBuilder);
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		String inId = null;
		for (SearchHit hit : search.getHits().getHits()) {
			inId = hit.getId();
		}
		UpdateRequest updateRequest = new UpdateRequest("fj", inId);
		updateRequest.timeout("1s");
		HashMap<String,Object> data=new HashMap<>();
		data.put("verifyState",1);
		updateRequest.doc(JSON.toJSONString(data), XContentType.JSON);
		UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		log.info(String.valueOf(update.status()));
		return Result.ok().message("ElasticSearch审核通过");
	}
	//搜索功能常规
	public Result searchPage(String keyword) throws IOException {
//		if(page<=1){
//			page=1;
//		}
		//条件搜索
		SearchRequest searchRequest = new SearchRequest("fj");
		//构建搜索条件
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		sourceBuilder.highlighter();
		//查询条件 QueryBuilders工具类实现
		//termQuery精确匹配
		//matchAllQuery匹配所有
		//multiMatchQuery 多字段匹配
		//组合查询
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
				.must(QueryBuilders.multiMatchQuery(keyword, "address","addressInfo","houseDescribe"))
				.must(QueryBuilders.termQuery("verifyState", "2"));
//		MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
		sourceBuilder.query(boolQueryBuilder);
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		//分页
//		sourceBuilder.from(page);
//		sourceBuilder.size(size);
		//高亮
		HighlightBuilder highlightBuilder=new HighlightBuilder();
		highlightBuilder.field("address");
		highlightBuilder.field("addressInfo");
		highlightBuilder.field("houseDescribe");
		highlightBuilder.requireFieldMatch(false);
		highlightBuilder.preTags("<span style='color:red'>");
		highlightBuilder.postTags("</span>");
		sourceBuilder.highlighter(highlightBuilder);
		//执行搜索
		searchRequest.source(sourceBuilder);
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		ArrayList<Map<String,Object>> list = new ArrayList<>();
		for (SearchHit hit : search.getHits().getHits()) {
			Map<String, HighlightField> highlightFields=hit.getHighlightFields();
			HighlightField address = highlightFields.get("address");
			HighlightField addressInfo = highlightFields.get("addressInfo");
			HighlightField houseDescribe = highlightFields.get("houseDescribe");
			Map<String,Object> sourceMap=hit.getSourceAsMap();
			//解析高亮字段,将原有字段替换
			if (address!=null){
				Text[] fragments = address.fragments();
				String n_address="";
				for (Text fragment : fragments) {
					n_address+=fragment;
				}
				sourceMap.put("address",n_address);
			}
			if (addressInfo!=null){
				Text[] fragments1 = addressInfo.fragments();
				String n_addressInfo="";
				for (Text text : fragments1) {
					n_addressInfo+=text;
				}
				sourceMap.put("addressInfo",n_addressInfo);
			}
			if (houseDescribe!=null){
				Text[] fragments2 = houseDescribe.fragments();
				String n_houseDescribe="";
				for (Text text : fragments2) {
					n_houseDescribe+=text;
				}
				sourceMap.put("houseDescribe",n_houseDescribe);
			}
			list.add(sourceMap);
		}
		if (list.size()>0){
			return Result.ok().data(list);
		}else {
			throw new BusinessException(ResultCode.HOUSEINFO_EXAMINE_FAIL.getCode(), "满足条件的房屋不存在");
		}

	}

	//搜索功能根据房屋类型
	public Result searchHouse(String keyword) throws IOException {
//		if(page<=1){
//			page=1;
//		}
		//条件搜索
		SearchRequest searchRequest = new SearchRequest("fj");
		//构建搜索条件
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		sourceBuilder.highlighter();
		//查询条件 QueryBuilders工具类实现
		//termQuery精确匹配
		//matchAllQuery匹配所有
		//multiMatchQuery 多字段匹配
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
				.must(QueryBuilders.termQuery("houseType", keyword))
				.must(QueryBuilders.termQuery("verifyState", "2"));
//		MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
		//执行搜索
		sourceBuilder.query(boolQueryBuilder);
//		sourceBuilder.from();
//		sourceBuilder.size();
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		searchRequest.source(sourceBuilder);
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		ArrayList<Map<String,Object>> list = new ArrayList<>();
		for (SearchHit hit : search.getHits().getHits()) {
			list.add(hit.getSourceAsMap());
		}
		if (list.size()>0){
			return Result.ok().data(list);
		}else {
			throw new BusinessException(ResultCode.HOUSEINFO_EXAMINE_FAIL.getCode(), "满足条件的房屋不存在");
		}

	}

	//搜索功能根据装修情况
	public Result searchDecorate(String keyword) throws IOException {
//		if(page<=1){
//			page=1;
//		}
		//条件搜索
		SearchRequest searchRequest = new SearchRequest("fj");
		//构建搜索条件
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		sourceBuilder.highlighter();
		//查询条件 QueryBuilders工具类实现
		//termQuery精确匹配
		//matchAllQuery匹配所有
		//multiMatchQuery 多字段匹配
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
				.must(QueryBuilders.termQuery("decorateState", keyword))
				.must(QueryBuilders.termQuery("verifyState", "2"));
//		MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
		//执行搜索
		sourceBuilder.query(boolQueryBuilder);
//		sourceBuilder.from();
//		sourceBuilder.size();
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		searchRequest.source(sourceBuilder);
		SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		ArrayList<Map<String,Object>> list = new ArrayList<>();
		for (SearchHit hit : search.getHits().getHits()) {
			list.add(hit.getSourceAsMap());
		}
		if (list.size()>0){
			return Result.ok().data(list);
		}else {
			throw new BusinessException(ResultCode.HOUSEINFO_EXAMINE_FAIL.getCode(), "满足条件的房屋不存在");
		}

	}
}
